package com.eian.boot.metrics.config;

import com.eian.boot.metrics.aspect.PackageScanMonitorAspect;
import com.eian.boot.metrics.aspect.PerformanceMonitorAspect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * 性能监控自动配置类
 *
 * @author alex.meng
 */
@Slf4j
@AutoConfiguration
@EnableAspectJAutoProxy
@EnableConfigurationProperties(MetricsProperties.class)
@ConditionalOnProperty(prefix = "eian.metrics", name = "enabled", havingValue = "true", matchIfMissing = true)
public class MetricsAutoConfiguration {

    /**
     * 性能监控AOP切面
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "eian.metrics", name = "enabled", havingValue = "true", matchIfMissing = true)
    public PerformanceMonitorAspect performanceMonitorAspect(
            MetricsProperties metricsProperties) {
        log.info("Initializing PerformanceMonitorAspect with collect.enabled: {}",
                metricsProperties.getCollect().isEnabled());
        return new PerformanceMonitorAspect(metricsProperties);
    }

    /**
     * 包扫描监控AOP切面
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "eian.metrics.scan", name = "enabled", havingValue = "true")
    public PackageScanMonitorAspect packageScanMonitorAspect(
            MetricsProperties metricsProperties) {
        log.info("Initializing PackageScanMonitorAspect with enabled: {}, base packages: {}, collect.enabled: {}",
                metricsProperties.getScan().isEnabled(),
                metricsProperties.getScan().getBasePackages(),
                metricsProperties.getCollect().isEnabled());
        return new PackageScanMonitorAspect(metricsProperties);
    }

    /**
     * 配置信息日志输出
     */
    @Bean
    public MetricsConfigurationLogger metricsConfigurationLogger(MetricsProperties metricsProperties) {
        return new MetricsConfigurationLogger(metricsProperties);
    }

    /**
     * 配置信息日志记录器
     */
    public static class MetricsConfigurationLogger {

        public MetricsConfigurationLogger(MetricsProperties metricsProperties) {
            logConfiguration(metricsProperties);
        }

        private void logConfiguration(MetricsProperties properties) {
            if (!properties.isEnabled()) {
                return;
            }

            log.debug("========== 性能监控配置 ==========");
            // 日志配置
            var logConfig = properties.getLog();
            log.debug("启用日志输出: {}, 日志级别: {}, 输出详细信息: {}",
                    logConfig.isEnabled(), logConfig.getLevel(), logConfig.isVerbose());

            // 扫描配置
            if (properties.getScan().isEnabled()) {
                var scanConfig = properties.getScan();
                log.debug("启用包扫描监控");
                log.debug("包扫描基础包路径: {}", scanConfig.getBasePackages());
                log.debug("包含的类名模式: {}", scanConfig.getIncludeClassPatterns());
                log.debug("排除的类名模式: {}", scanConfig.getExcludeClassPatterns());
                log.debug("包含的方法名模式: {}", scanConfig.getIncludeMethodPatterns());
                log.debug("排除的方法名模式: {}", scanConfig.getExcludeMethodPatterns());
            }

            // 性能配置
            var perfConfig = properties.getPerformance();
            log.debug("性能指标配置 - 慢方法阈值: {}ms, 采样率: {}",
                    perfConfig.getSlowThreshold(), perfConfig.getSampleRate());
            log.debug("性能参数记录配置 - 记录参数: {}, 记录返回值: {}, 内存监控: {}",
                    perfConfig.isRecordArgs(), perfConfig.isRecordResult(), perfConfig.isMemoryMonitoring());

            // 数据收集配置
            var collectConfig = properties.getCollect();
            log.debug("数据收集（启用该项需要实现PerformanceCollector接口）: {}", collectConfig.isEnabled());

            // 告警配置
            var alertConfig = properties.getAlert();
            if (alertConfig.isEnabled()) {
                log.debug("告警配置 - 告警阈值: {}ms, 告警频率限制: {}s, 告警接收邮箱: {}",
                        alertConfig.getThreshold(), alertConfig.getRateLimitSeconds(), alertConfig.getEmails());
            }
            log.debug("========================================");
            log.info("性能监控配置加载完成");
        }
    }
}
